const pool = require('../models/db');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const fs = require('fs');

const privateKey = fs.readFileSync('./certs/localhost+2-key.pem');
const publicKey = fs.readFileSync('./certs/localhost+2.pem');
const saltRounds = 10;  // 设置加密的盐值轮数

// 登录
const login = async (data) => {
  const { username: account_nickname, password: account_password } = data;
  const results = await pool.query('SELECT * FROM accounts WHERE account_nickname = $1', [account_nickname]);
  if (results.rowCount === 0) {
    throw new Error('Invalid account nickname or password');
  }

  const user = results.rows[0];
  const isMatch = await bcrypt.compare(account_password, user.account_password);
  if (!isMatch) {
    throw new Error('Invalid account password');
  }
  
  // 密码匹配成功，生成 JWT token
  const token = jwt.sign({ account_id: user.account_id, account_nickname: user.account_nickname, permission_level: user.permission_level }, privateKey, { algorithm: 'RS256', expiresIn: '1h' });
  // 返回 token 给客户端，客户端应将 token 存储在本地存储或 cookie 中，以便在后续请求中使用
  return { message: 'Login successful', token: token };
};

// 验证 token
const verifyToken = (token) => {
  return new Promise((resolve, reject) => {
    jwt.verify(token, publicKey, { algorithm: 'RS256' }, (err, decoded) => {
      if (err) {
        return reject('Invalid token');
      }
      resolve(decoded);
    });
  });
};

// 获取个人信息
const getPersonalInfo = async (req) => {
  try {
    const { authorization } = req.headers;
    if (!authorization) {
      throw new Error('Authorization header is missing');
    }

    const token = authorization.split(' ')[1]; // 提取 Bearer Token
    const decoded = await verifyToken(token); // 验证 Token

    // Token 验证通过后，获取用户信息
    const { account_id } = decoded;
    const results = await pool.query('SELECT * FROM accounts WHERE account_id = \$1', [account_id]);

    if (results.rowCount === 0) {
      throw new Error('Invalid account nickname');
    }

    const user = results.rows[0];
    return user;  // 返回用户信息
  } catch (error) {
    console.error('Error retrieving personal info:', error);
    throw new Error('Failed to retrieve personal info');
  }
};

// 更新个人信息
const updatePersonalInfo = async (req) => {
  const client = await pool.connect();
  try {
    const { authorization } = req.headers;
    if (!authorization) {
      throw new Error('Authorization header is missing');
    }

    const token = authorization.split(' ')[1]; // 提取 Bearer Token
    const decoded = await verifyToken(token); // 验证 Token
    const { account_id } = decoded;

    await client.query('BEGIN');
    const { account_nickname, account_password, full_name, gender, contact_info, remarks } = req.body;
    const hashedPassword = await bcrypt.hash(account_password, saltRounds);
    const results = await client.query(
      'UPDATE accounts SET account_nickname = $1, account_password = $2, full_name = $3, gender = $4, contact_info = $5, remarks = $6 WHERE account_id = $7 RETURNING *',
      [account_nickname, hashedPassword, full_name, gender, contact_info, remarks, account_id]
    );
    if (results.rowCount === 0) {
      throw new Error('No account found with this nickname');
    }
    await client.query('COMMIT');
    return results.rows[0];
  } catch (error) {
    await client.query('ROLLBACK');
    throw error;
  } finally {
    client.release();
  }
};

// 获取员工信息
const getEmployees = async (query) => {
  const { account_id, account_nickname, permission_level, full_name, gender, contact_info, remarks } = query;
  let sqlQuery = 'SELECT * FROM accounts';
  let conditions = [];
  let values = [];

  if (account_id) {
    conditions.push('account_id = $' + (conditions.length + 1));
    values.push(account_id);
  }
  if (account_nickname) {
    conditions.push('account_nickname ILIKE $' + (conditions.length + 1));
    values.push(`%${account_nickname}%`);
  }
  if (permission_level !== undefined) {
    conditions.push('permission_level = $' + (conditions.length + 1));
    values.push(permission_level);
  }
  if (full_name) {
    conditions.push('full_name ILIKE $' + (conditions.length + 1));
    values.push(`%${full_name}%`);
  }
  if (gender !== undefined) {
    conditions.push('gender = $' + (conditions.length + 1));
    values.push(gender);
  }
  if (contact_info) {
    conditions.push('contact_info ILIKE $' + (conditions.length + 1));
    values.push(`%${contact_info}%`);
  }
  if (remarks) {
    conditions.push('remarks ILIKE $' + (conditions.length + 1));
    values.push(`%${remarks}%`);
  }

  if (conditions.length > 0) {
    sqlQuery += ' WHERE ' + conditions.join(' AND ');
  }

  const results = await pool.query(sqlQuery, values);
  return { items: results.rows, total: results.rowCount };
};

// 新增员工
const addEmployee = async (data) => {
  const client = await pool.connect();
  try {
    await client.query('BEGIN');
    const { account_nickname, account_password, permission_level, full_name, gender, contact_info, remarks } = data;
    const hashedPassword = await bcrypt.hash(account_password, saltRounds);
    const results = await client.query(
      'INSERT INTO accounts (account_nickname, account_password, permission_level, full_name, gender, contact_info, remarks) VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING *',
      [account_nickname, hashedPassword, permission_level, full_name, gender, contact_info, remarks || null]
    );
    await client.query('COMMIT');
    return results.rows[0];
  } catch (error) {
    await client.query('ROLLBACK');
    throw error;
  } finally {
    client.release();
  }
};

// 更新员工信息
const updateEmployee = async (id, data) => {
  const client = await pool.connect();
  try {
    await client.query('BEGIN');
    const { account_nickname, account_password, permission_level, full_name, gender, contact_info, remarks } = data;
    const hashedPassword = await bcrypt.hash(account_password, saltRounds);
    const results = await client.query(
      'UPDATE accounts SET account_nickname = $1, account_password = $2, permission_level = $3, full_name = $4, gender = $5, contact_info = $6, remarks = $7 WHERE account_id = $8 RETURNING *',
      [account_nickname, hashedPassword, permission_level, full_name, gender, contact_info, remarks || null, id]
    );
    if (results.rowCount === 0) {
      throw new Error('No account found with this ID');
    }
    await client.query('COMMIT');
    return results.rows[0];
  } catch (error) {
    await client.query('ROLLBACK');
    throw error;
  } finally {
    client.release();
  }
};

// 删除员工
const deleteEmployee = async (id) => {
  const client = await pool.connect();
  try {
    await client.query('BEGIN');
    const results = await client.query('DELETE FROM accounts WHERE account_id = $1 RETURNING *', [id]);
    if (results.rowCount === 0) {
      throw new Error('No account found with this ID');
    }
    await client.query('COMMIT');
  } catch (error) {
    await client.query('ROLLBACK');
    throw error;
  } finally {
    client.release();
  }
};

// 获取建议
const getSuggestions = async (query) => {
  const { field, query: searchString } = query;
  const results = await pool.query(
    `SELECT DISTINCT ${field} FROM accounts WHERE ${field} ILIKE $1`,
    [`%${searchString}%`]
  );
  return results.rows.map(row => row[field]);
};

module.exports = {
  login,
  verifyToken,
  getPersonalInfo,
  updatePersonalInfo,
  getEmployees,
  addEmployee,
  updateEmployee,
  deleteEmployee,
  getSuggestions,
};
